/*
 * Copyright 2007 Rob Nielsen
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.proxymatic.core;

import java.lang.reflect.Method;

/**
 * Method invokers are created from MethodHandlers and one is assigned to each method in the target interfaces. When one
 * of these method is invoked on the proxy, the appropriate MethodInvoker is called.  The method invoker should perform
 * some kind of calculation or pass off to another class and return an object of an appropriate type for
 * method.getReturnType().  Primitive return types must be box in it's equivalent object.  Method invokers should avoid
 * searching for appropriate methods.  This should all be performed by the MethodHandler at buildtime.
 */
public interface MethodInvoker {
    Class[] NO_DECLARED_EXCEPTIONS = {};

    /**
     * Invokes a method.
     *
     * @param method     the target interface method that has been invoked
     * @param parameters the parameters that were passed to the method call.
     * @param context    the runtime context.  This wraps up the buildtimecontext with implementation objects, if
     *                   appropriate.
     * @return the result to return to the caller of the method.  Must be assignable from method.getReturnType()
     * @throws Throwable if any problems occur in the invocation.
     */
    Object invoke(Method method, Object[] parameters, RuntimeContext context) throws Throwable;

    /**
     * Returns the exceptions that are known to be thrown by this method.  Only checked exceptions are required.
     *
     * @return an array of exceptions types, or NO_DECLARED_EXCEPTION if only RuntimeExceptions are thrown.
     */
    Class[] getExceptionTypes();
}
